﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms.DataVisualization.Charting;
using System.Collections;

namespace ProfilerPOC
{

    
    public partial class PoSHProfiler : Form
    {
        delegate void SetOutputTextBoxCallback(string text);
        delegate void SetPerfChartCallback(DataPoint[] counters);
        delegate void SetDGStatementCallback(string text);
        ProcessLaunchAndMonitor PLM;
        Instrumentor inst = new Instrumentor();

        public bool sourceViewShown = false;

        Hashtable IDTracker = new Hashtable();
        int dgCounter = 0;
        

       

        public PoSHProfiler()
        {
            InitializeComponent();
            PLM = new ProcessLaunchAndMonitor();
            PLM.RaiseOutputReceived += new EventHandler(PLM_RaiseOutputReceived);
            PLM.PerfDataUpdated += new EventHandler(PLM_PerfDataUpdated);
            PLM.RaiseProfilerStatement += new EventHandler(PLM_RaiseProfilerStatement);

            
            
        }

        void button1_Click(object sender, EventArgs e)
        {

            button2.Enabled = false;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                inst.Path = openFileDialog.FileName;
            }
            string updatedFilePath = Environment.GetEnvironmentVariable("LocalAppData");
            inst.InstrumentScript();
            System.IO.File.WriteAllText(string.Format("{0}\\PoSHProfilerScript.ps1", updatedFilePath),inst.InstrumentedScript.ToString());
            button2.Enabled = true;
                       
        }

        
              
        private void button2_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
           
            button2.Enabled = false;
            
            PLM.SpinUpProcess();
        
        }

        void PLM_RaiseProfilerStatement(object sender, EventArgs e)
        {
            this.SetDGStatement(sender.ToString());
        }
        void PLM_PerfDataUpdated(object sender, EventArgs e)
        {
            this.SetPerfChart();
        }

        void PLM_RaiseOutputReceived(object sender, EventArgs e)
        {
            this.SetOutput(sender.ToString());
        }

        private void SetDGStatement(string statement)
        {
            if (this.dataGridView1.InvokeRequired)
            {
                SetDGStatementCallback dgCallback = new SetDGStatementCallback(SetDGStatement);
                this.Invoke(dgCallback, new object[] { statement });
            }
            else
            {
                updateDG(statement);
            }
        }

        private void updateDG(string traceInfo)
        {
            string[] statements = traceInfo.Split(',');
            int index = dgCounter;
            int tmpIndex = 0;
            Debug.WriteLine("enter updateDG: " + traceInfo);
            dataGridView1.Rows.Add(1);
            dataGridView1.AutoResizeColumns();

            // ID has been passed, need to see if this ID has been passed previously.  If so, update the row that it was initially pass in.
            // If not, log it along with the current index.
            if (statements[4] != " ")
            {
                if (IDTracker.ContainsKey(statements[4].ToString().Trim()))
                {
                    tmpIndex = index;  //so we know where we are before going back to update the DG
                    index = ((int)IDTracker[statements[4].ToString().Trim()]);
                    
                    Debug.WriteLine("IDTracker.containsKey: " + index);

                }
                else
                {
                    IDTracker.Add(statements[4].Trim(), dgCounter);
                    index = dgCounter;
                    Debug.WriteLine("No key found: " + index);
                }

            }
            Debug.WriteLine("index: " + index);

            //Index
            dataGridView1.Rows[index].Cells[0].Value = index;

            //line 
            dataGridView1.Rows[index].Cells[1].Value = statements[0];

            //Expression
            dataGridView1.Rows[index].Cells[2].Value = statements[1];

            //Execution Time
            dataGridView1.Rows[index].Cells[3].Value = statements[2];

            //TotalTime
            dataGridView1.Rows[index].Cells[4].Value = statements[3];

            if (tmpIndex == 0)
            {
                dgCounter++;
                
            }

            
            
        }
        
        private void SetOutput(string text)
        {
            if (this.OutputTextBox.InvokeRequired)
            {
                SetOutputTextBoxCallback otbCallback = new SetOutputTextBoxCallback(SetOutput);
                this.Invoke(otbCallback, new object[] { text });
            }
            else
            {
                OutputTextBox.AppendText(text + Environment.NewLine);
            }
        }

        private void SetPerfChart()
        {
            
                chart1.Series[0].Points.Add(PLM.CPU_DP.YValues[0]);
                chart1.Series[0].Name = String.Format("CPU - {0:F2}", PLM.CPU_DP.YValues[0].ToString());
                chart1.Series[1].Points.Add(PLM.MEM_DP.YValues[0]);
                chart1.Series[1].Name = String.Format("Memory - {0:F2}MB", PLM.MEM_DP.YValues[0].ToString());
            
        }

        private void parametersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ParamFetch fetch = new ParamFetch();
            fetch.Show();
        }

        private void sourceView_Shown(object sender, EventArgs e)
        {
            sourceViewShown = true;
        }
        
       

    }


}//end namespace
